//============================================================================
// Name        : ProgettoElaborazioneDati3D.cpp
// Author      : Roberto
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <opencv/cv.h>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;



Mat img, src_gray , dst, detected_edges;

int edgeThresh = 1;
int lowThreshold ;
int const max_lowThreshold = 200;
int ratio = 3;
int kernel_size = 3;
char* window_name = "Edge Map";

/**
 * @function CannyThreshold
 * @brief Trackbar callback - Canny thresholds input with a ratio 1:3
 */
void CannyThreshold(int, void*)
{
  /// Reduce noise with a kernel 3x3
  blur( src_gray, detected_edges, Size(3,3) );

  /// Canny detector
  Canny( detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size );

  /// Using Canny's output as a mask, we display our result
  dst = Scalar::all(50);

  img.copyTo( dst, detected_edges);
  imshow( window_name, dst );

  imwrite("/home/roberto/Scrivania/result.bmp",dst);
}

int main(int argc, char** argv){


	img = imread("/home/roberto/Scrivania/01_3d_crepe(copia).bmp" );
	Mat img2 = imread("/home/roberto/Scrivania/01_3d.bmp");

	if (img.empty())
	{
		cout << "Image cannot be loaded..!!" << endl;
		return -1;
	}

	//Mat imgL = img + Scalar(-75, -75, -75); //decrease the brightness by 75 units
	//img.convertTo(imgL, -1, 1, -75);
	//imgL.convertTo(imgL, -1, 1.2, 0); //decrease the contrast (halve)

	//create windows
	//namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
	//namedWindow("After Contrast and Brightness", CV_WINDOW_AUTOSIZE);

	//show the image
	//imshow("Original Image", img);
	//imshow("After Contrast and Brightness", imgL);
	//waitKey(0); //wait for key press

	//bitwise_not(img, img);
	//cvNamedWindow("Invert");
	//imshow("Invert", img);
/*
	// Create a matrix of the same type and size as src (for dst)
	dst.create( img.size(), img.type() );

	// Convert the image to grayscale
	cvtColor( img, src_gray, CV_BGR2GRAY );

	// Create a window
	namedWindow( window_name, CV_WINDOW_AUTOSIZE );

	/// Create a Trackbar for user to enter threshold
	createTrackbar( "Min Threshold:", window_name, &lowThreshold, max_lowThreshold, CannyThreshold );

	// Show the image
	CannyThreshold(0, 0);

	// Wait until user exit program by pressing a key
	waitKey(0);

	//destroyAllWindows(); //destroy all open windows

/*

	//EROSIONE
	int row = 2;
	int cols = 2;
	Size size;
	size.height = row ;
	size.width = cols ;


	Point point;
	point.x = point.y = -1 ;

	//crea l’elemento strutturante
	Mat element = getStructuringElement(CV_SHAPE_RECT, size,point);

	erode(imgL,imgL,element,point,1);
	imshow("IMG EROSIONE", imgL);
	waitKey(0);



*/

	// Convert the image to grayscale
	//cvtColor( dst, dst, CV_BGR2GRAY );

	// detecting keypoints
    // SIFT feature detector and feature extractor
    SiftFeatureDetector detector( 0.05, 4.0 );
	vector<KeyPoint> keypoints1, keypoints2 ;
	detector.detect(img, keypoints1);
	detector.detect(img2, keypoints2);

	// computing descriptors
	SiftDescriptorExtractor extractor( 3.0 );
	Mat descriptors1, descriptors2 ;
	extractor.compute(img, keypoints1, descriptors1);
	extractor.compute(img2, keypoints2, descriptors2);


	// matching descriptors
	BruteForceMatcher<L2<float> > matcher;
	vector<DMatch> matches;
	matcher.match(descriptors1, descriptors2, matches);

	// drawing the results
	namedWindow("matches", 1);
	Mat img_matches;
	drawMatches(img, keypoints1, img2, keypoints2, matches, img_matches);
	imshow("matches", img_matches);
	imwrite("/home/roberto/Scrivania/result_match.bmp",img_matches);
	waitKey(0);


	return 0;

}
